#include "Logger.h"

namespace GeorgeLib
{

	// Initialise all our static pointers to NULL first
	// before we do anything, except our LuaState
	// LuaState will be handled by lualib
	_Logger*	_Logger::Logger_Instance = NULL;
	char*		_Logger::Destination = "Logger.txt";
	ofstream	_Logger::FileStream;

	// Constructor	: no file name, _Logger will output to console
	_Logger::_Logger(void) {}

	// Destructor	: Close the output file stream
	_Logger::~_Logger(void)
	{
		CloseFile();

		// Delete the Instance
		if (Logger_Instance != NULL)
		{
			delete Logger_Instance;
			Logger_Instance = NULL;
		}
	}

	_Logger* _Logger::getInstance(void)
	{
		if (Logger_Instance == NULL)
			Logger_Instance = new _Logger();

		return Logger_Instance;
	}

	void _Logger::AddLog(string message, bool endline, bool timestamp)
	{
		AddLog(const_cast<char*>(message.c_str()), timestamp, endline);
	}

	void _Logger::AddLog(char * message, bool endline, bool timestamp)
	{
		// Open file if it's not open
		// ios::out : Output only
		// ios::app : Append, write from the end of the file
		if (!FileStream.is_open()) FileStream.open(Destination, ios::out | ios::app);

		// eg. Mar  1 2013 15:38:00
		if (timestamp) FileStream << __DATE__ << " " << __TIME__ << " ";

		FileStream << message;

		// endline will always be true unless specified
		if (endline) FileStream << endl;
	}

	void _Logger::LoadFile(char * filename)
	{
		// Close the file first, if there is any
		CloseFile();

		// Redefine the output file destination
		// AddLog() will open the file before output
		Destination = filename;
	}

	void _Logger::CloseFile(void)
	{
		// Close the file only if there is a file open on FileStream
		if (FileStream.is_open()) FileStream.close();
	}

	_Logger& operator<< (_Logger & logger, string var)
	{
		Logger->AddLog((char*)var.c_str(), false, false);
		return logger;
	}

	_Logger& operator<< (_Logger & logger, __int8 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, unsigned __int8 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, __int16 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, unsigned __int16 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, __int32 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, unsigned __int32 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, __int64 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, unsigned __int64 var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, float var)
	{
		logger.FileStream << var;
		return logger;
	}

	_Logger& operator<< (_Logger & logger, double var)
	{
		logger.FileStream << var;
		return logger;
	}

} // namespace GeorgeLib